package com.samehope.ar.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.samehope.ar.constant.DelFlagEnum;
import com.samehope.ar.constant.QuestionStatusEnum;
import com.samehope.ar.dto.*;
import com.samehope.ar.entity.Problem;
import com.samehope.ar.entity.ProblemReply;
import com.samehope.ar.mapper.ProblemMapper;
import com.samehope.ar.service.IProblemReplyService;
import com.samehope.ar.service.IProblemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.samehope.ar.util.DateUtils;
import com.samehope.ar.util.SessionUtil;
import com.samehope.ar.vo.PaginationDataVO;
import com.samehope.ar.vo.ProblemDetailVO;
import com.samehope.ar.vo.ProblemTableVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 问题 服务实现类
 * </p>
 *
 * @author Zhang Luo
 * @since 2019-12-23
 */
@Service
public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> implements IProblemService {

    @Autowired
    private IProblemReplyService replyService;

    /**
     * 删除问题单
     * @param problemId
     */
    @Override
    public void deleteProblem(Long problemId) {
        Problem problem = this.baseMapper
                .findByProjectAndProblem(SessionUtil.getProjectId(), problemId);

        if (problem == null) {
            throw new IllegalArgumentException("问题单不存在");
        }

        problem.setDelFlag(DelFlagEnum.DELETED.getCode());
        problem.setUpdateBy(SessionUtil.getUserId());
        problem.setUpdateDate(LocalDateTime.now());

        this.updateById(problem);
    }

    /**
     * 新增问题单
     * @param param
     */
    @Override
    public void add(ProblemAddParam param) {

        Problem problem = new Problem();
        BeanUtils.copyProperties(param, problem);
        problem.setCompanyId(SessionUtil.getCompanyId());
        problem.setProjectId(SessionUtil.getProjectId());
        problem.setQuestionStatus(QuestionStatusEnum.NEW.getCode());
        problem.setCreateBy(SessionUtil.getUserId());
        problem.setCreateDate(LocalDateTime.now());

        this.save(problem);

    }

    /**
     * 更新问题单
     * @param param
     */
    @Override
    public void update(ProblemUpdateParam param) {

        Problem problem = this.baseMapper.findByProjectAndProblem(SessionUtil.getProjectId(), param.getProblemId());
        if (problem == null) {
            throw new IllegalArgumentException("问题单不存在");
        }

        if (QuestionStatusEnum.OVER.getCode().equals(problem.getQuestionStatus())) {
            throw new IllegalArgumentException("问题单已结束, 无法编辑");
        }

        BeanUtils.copyProperties(param, problem);
        problem.setUpdateBy(SessionUtil.getUserId());
        problem.setUpdateDate(LocalDateTime.now());

        this.updateById(problem);
    }

    /**
     * 问题单详情
     * @param problemId
     * @return
     */
    @Override
    public ProblemDetailVO detail(Long problemId) {
        ProblemDetailVO detailVO = this.baseMapper.findDetailByProjectAndProblem(SessionUtil.getProjectId(), problemId);

        if (detailVO == null) {
            throw new IllegalArgumentException("问题单不存在");
        }
        Long minutes;
        if (QuestionStatusEnum.OVER.getCode().equals(detailVO.getQuestionStatus())) {
            minutes = Duration.between(DateUtils.toLocalDateTime(detailVO.getCreateTime()),
                    DateUtils.toLocalDateTime(detailVO.getHandTime())).toMinutes();
        } else {
            minutes = Duration.between(DateUtils.toLocalDateTime(detailVO.getCreateTime()),
                    LocalDateTime.now()).toMinutes();
        }

        String hourStr = minutes / 60 + "小时";
        String minuteStr = minutes % 60 + "分钟";

        detailVO.setWaitTime("已等待" + (minutes > 60 ?  hourStr + minuteStr : minuteStr));
        return detailVO;
    }

    /**
     * 回复问题单
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void reply(ReplyParam param) {

        Problem problem = this.baseMapper.findByProjectAndProblem(SessionUtil.getProjectId(), param.getProblemId());

        if (problem == null) {
            throw new IllegalArgumentException("问题单不存在");
        }

        ProblemReply problemReply = replyService.findByProblem(param.getProblemId());
        if (problemReply != null) {
            throw new IllegalArgumentException("问题单已被回复, 请勿重复回复");
        }

        problem.setQuestionStatus(QuestionStatusEnum.OVER.getCode());
        problem.setUpdateBy(SessionUtil.getUserId());
        problem.setUpdateDate(LocalDateTime.now());
        this.updateById(problem);

        problemReply = new ProblemReply();
        problemReply.setProblemId(param.getProblemId());
        problemReply.setReply(param.getReply());
        problemReply.setCreateBy(SessionUtil.getUserId());

        replyService.save(problemReply);
    }

    /**
     * 分配问题
     * @param param
     */
    @Override
    public void allot(ProblemAllotParam param) {

        Problem problem = this.baseMapper.findByProjectAndProblem(SessionUtil.getProjectId(), param.getProblemId());

        if (problem == null) {
            throw new IllegalArgumentException("问题单不存在");
        }

        problem.setHandBy(param.getHandBy());
        problem.setQuestionStatus(QuestionStatusEnum.LOADING.getCode());
        problem.setUpdateBy(SessionUtil.getUserId());
        problem.setUpdateDate(LocalDateTime.now());
        this.updateById(problem);
    }

    /**
     * 分页查询问题清单
     * @param paginationParam
     * @param problemQueryParam
     * @return
     */
    @Override
    public PaginationDataVO<ProblemTableVO> problems(PaginationParam paginationParam, ProblemQueryParam problemQueryParam) {

        Page<ProblemTableVO> page = new Page<>(paginationParam.getPageNum(), paginationParam.getPageSize());

        List<ProblemTableVO> problems = this.baseMapper
                .problemsByProjectAndParam(page, SessionUtil.getProjectId(), problemQueryParam);

        page.setRecords(problems);

        return PaginationDataVO.of(page);
    }
}
